package com.itcv.spring.oauth.demo.config;

import com.itcv.spring.oauth.demo.config.login.AdminPwdAuthenticationProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.actuate.autoconfigure.security.servlet.EndpointRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.BeanIds;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

/**
 * @author : Windy
 * @version :1.0
 * @since : 2020/12/8 16:13
 */
@Configuration
@EnableWebSecurity
@EnableAuthorizationServer
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    private static final String[] excludedAuthPages = {"/login/**",};
    @Override
    @Bean(name = BeanIds.AUTHENTICATION_MANAGER)
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories.createDelegatingPasswordEncoder();
    }

	@Bean
	@Override
	public UserDetailsService userDetailsService() {
		// 测试方便采用内存存取方式
		InMemoryUserDetailsManager userDetailsService = new InMemoryUserDetailsManager();
		userDetailsService.createUser(User.withUsername("user_1").password(passwordEncoder().encode("123456")).authorities("ROLE_USER").build());
		userDetailsService.createUser(User.withUsername("user_2").password(passwordEncoder().encode("1234567")).authorities("ROLE_USER").build());
		return userDetailsService;
	}






    @Autowired
    private AdminPwdAuthenticationProvider adminPwdAuthenticationProvider;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
    	//此处注入一个默认的service，也可以不注入，我做测试时使用，根据需求，该service非admin-userservice
        auth.userDetailsService(userDetailsService());
        //添加两个Provider
       // auth.authenticationProvider(adminSmsAuthenticationProvider);
        auth.authenticationProvider(adminPwdAuthenticationProvider);
    }


    //安全拦截机制（最重要）
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.headers().contentTypeOptions().disable()
                .frameOptions().sameOrigin()
                .and()
                .authorizeRequests()
                .antMatchers(excludedAuthPages).permitAll()
                .antMatchers(HttpMethod.OPTIONS).permitAll()
                .requestMatchers(EndpointRequest.toAnyEndpoint()).permitAll()
                .and().authorizeRequests()
                .anyRequest().authenticated()
                .and().formLogin().disable()
                .exceptionHandling()
                .and().csrf().disable()
                .logout().disable().authorizeRequests();
    }
}
